package com.zimi.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zimi.mapper.*;
import com.zimi.model.*;
import com.zimi.util.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 机构职务表 Service
 *
 * @author lnintr
 * @since 2019-05-22
 */
@Service
public class SysPostService {
    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private SysOrgMapper sysOrgMapper;

    @Autowired
    private SysDutyMapper sysDutyMapper;

    @Autowired
    private SysDutyPrivilegeMapper sysDutyPrivilegeMapper;

    @Autowired
    private SysPostPrivilegeMapper sysPostPrivilegeMapper;

    @Autowired
    private SysPostUserMapper sysOrgExtendMapper;

    /*
     * 取得指定用户的岗位一览
     * */
    public List<SysOrgExtend> getPostList(int userId) {
        List<SysOrgExtend> postList = sysPostMapper.selectPostListByUserId(userId);
        return postList;
    }

    /*
     * 取得组织和角色信息
     * */
    public List<SysOrgExtend> getPostlistByOrg(List<Integer> orgIds) {
        // 1)取出机构一览
        List<SysOrg> orgList = sysOrgMapper.selectList(new QueryWrapper<SysOrg>().lambda().in(SysOrg::getId, orgIds));
        List<SysOrgExtend> postList = null;
        SysOrgExtend tmpOrg = null;
        SysOrg sysOrg = null;
        Map<Integer, SysOrg> ognMap = new HashMap<>();

        if (orgList != null && orgList.size() > 0) {
            List<Integer> ognIds = new ArrayList<>();

            for (SysOrg so : orgList) {
                ognIds.add(so.getOgnId());
            }

            List<SysOrg> ognList = sysOrgMapper.selectList(new QueryWrapper<SysOrg>().lambda().in(SysOrg::getOgnId, ognIds));
            for (SysOrg so : ognList) {
                ognMap.put(so.getId(), so);
            }

            // 2)取出岗位一览
            postList = sysPostMapper.selectPostList(orgIds);

            if (postList == null || postList.size() == 0) {
                if (postList == null) {
                    postList = new ArrayList<>();
                }

                // 3)加入默认岗位
                for (SysOrg so : orgList) {
                    tmpOrg = new SysOrgExtend();

                    tmpOrg.setId(0);
                    tmpOrg.setDutyId(0);
                    tmpOrg.setOrgId(so.getId());
                    tmpOrg.setUpdateTime(so.getUpdateTime());
                    tmpOrg.setName(String.format("%s-%s", so.getOrgName(), ((SysOrg) ognMap.get(so.getOgnId())).getPostName()));
                    postList.add(tmpOrg);
                }
            } else {
                // 4)加入默认岗位
                Map<Integer, SysOrg> orgMap = new HashMap<>();

                for (SysOrg so : orgList) {
                    orgMap.put(so.getId(), so);
                }

                for (int i = postList.size() - 1; i >= 0; i--) {
                    sysOrg = orgMap.get(postList.get(i).getOrgId());

                    if (sysOrg != null) {
                        orgMap.remove(sysOrg.getId());

                        tmpOrg = new SysOrgExtend();

                        tmpOrg.setId(0);
                        tmpOrg.setDutyId(0);
                        tmpOrg.setOrgId(sysOrg.getId());
                        tmpOrg.setUpdateTime(sysOrg.getUpdateTime());
                        tmpOrg.setName(String.format("%s-%s", sysOrg.getOrgName(), ((SysOrg) ognMap.get(sysOrg.getOgnId())).getPostName()));

                        postList.add(i + 1, tmpOrg);
                    }
                }

                if (orgMap.size() > 0) {
                    for (Map.Entry<Integer, SysOrg> entry : orgMap.entrySet()) {
                        sysOrg = entry.getValue();

                        tmpOrg = new SysOrgExtend();

                        tmpOrg.setId(0);
                        tmpOrg.setDutyId(0);
                        tmpOrg.setOrgId(sysOrg.getId());
                        tmpOrg.setUpdateTime(sysOrg.getUpdateTime());
                        tmpOrg.setName(String.format("%s-%s", sysOrg.getOrgName(), ((SysOrg) ognMap.get(sysOrg.getOgnId())).getPostName()));

                        postList.add(tmpOrg);
                    }
                }
            }
        } else {
            postList = new ArrayList<>();
        }

        return postList;
    }

    @Transactional
    public void savePost(SysOrgExtend sysOrgExtend, int flag) {
        if (sysOrgExtend != null) {
            SysPost tmpPost = null;

            // 1）对要修改的对象加行锁
            SysPost result = sysPostMapper.selectOne(new QueryWrapper<SysPost>().lambda().eq(SysPost::getDutyId, sysOrgExtend.getDutyId()).eq(SysPost::getOrgId, sysOrgExtend.getOrgId()).last("for update"));

            SysUser user = UserUtil.getUser();
            Date updateTime = new Date();

            if (result != null) {
                if (result.getUpdateTime() != null) {
                    if (sysOrgExtend.getUpdateTime() != null && result.getUpdateTime().getTime() != sysOrgExtend.getUpdateTime().getTime()) {
                        throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
                    }
                }

                SysPostPrivilege sysPostPrivilege = null;

                result.setUpdateUser(user.getId());
                result.setUpdateTime(updateTime);
                result.setPostState(flag);
                result.updateById();

                if (flag == 2) {
                    sysPostPrivilege = new SysPostPrivilege().setUpdateUser(user.getId()).setUpdateTime(updateTime).setPrivilegeState(flag);
                    sysPostPrivilegeMapper.update(sysPostPrivilege, new UpdateWrapper<SysPostPrivilege>().lambda().eq(SysPostPrivilege::getPostId, result.getId()).eq(SysPostPrivilege::getPrivilegeState, 1));
                }
            } else {
                result = new SysPost();

                result.setCreateUser(user.getId());
                result.setCreateTime(updateTime);
                result.setOrgId(sysOrgExtend.getOrgId());
                result.setPostState(flag);
                result.setDutyId(sysOrgExtend.getDutyId());

                result.insert();
            }
        }
    }

    /*
     * @dutyPrivileges 职务权限一览
     * @postId 岗位编号
     * @userId 用户编号
     * @updateTime 创建时间
     * */
    private void insertPostPrivilege(List<SysDutyPrivilege> dutyPrivileges, Integer orgId, Integer postId, Integer userId, Date updateTime) {
        if (dutyPrivileges != null && dutyPrivileges.size() > 0) {
            SysPostPrivilege sysPostPrivilege = new SysPostPrivilege();
            sysPostPrivilege.setOrgId(orgId);
            sysPostPrivilege.setPostId(postId);
            sysPostPrivilege.setPrivilegeState(1);
            sysPostPrivilege.setCreateUser(userId);
            sysPostPrivilege.setCreateTime(updateTime);

            for (SysDutyPrivilege sdp : dutyPrivileges) {
                sysPostPrivilege.setId(null);
                sysPostPrivilege.setFunctionId(sdp.getFunctionId());

                sysPostPrivilege.insert();
            }
        }
    }

    /*
     * 根据id查询岗位
     * */
    public Object selectById(int id) {
        SysPost sysPost = sysPostMapper.selectById(id);
        int orgId = sysPost.getOrgId();
        int dutyId = sysPost.getDutyId();
        String orgName = sysOrgMapper.selectById(orgId).getOrgName();
        String dutyName = sysDutyMapper.selectById(dutyId).getDutyName();
        return orgName + "-" + dutyName;
    }

    /**
     * @author wh
     * @desc 更新数据
     */
    @Transactional
    public void update(SysPost sysPost) {
        // 1)给当前行加锁
        SysPost result = new SysPost().selectOne(new LambdaQueryWrapper<SysPost>().eq(SysPost::getId, sysPost.getId()).last("for update"));

        // 2)判断数据是否被修改
        if (result.getUpdateTime() != null) {
            if (sysPost.getUpdateTime() == null) {
                throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
            } else {
                if (result.getUpdateTime().getTime() != sysPost.getUpdateTime().getTime()) {
                    throw new RuntimeException("修改数据失败，数据已经被其他用户改过。");
                }
            }
        }

        //3) 更新数据
        Date dateTime = new Date();
        SysUser user = UserUtil.getUser();

        sysPost.setUpdateTime(dateTime);
        sysPost.setUpdateUser(user.getId());

        sysPost.updateById();
    }
}
